home *** CD-ROM | disk | FTP | other *** search
- /*********************************************************
- "window.c"
-
- by John A. Love, III [ Washington Apple Pi Users' Group]
-
- using Symantec's "THINK C", v 5.00
- *********************************************************/
-
-
- #include <string.h>
- #include <Palette.h>
-
- #include "protos"
-
- #include "globals.h"
- #include "extern.h"
-
- #include "floatingWindow.h"
-
-
- // Local Prototypes:
- void CalcWindowFrame (WindowPtr window, Rect *r);
- void CloseBehind (WindowPtr window);
-
-
- short windType;
- Boolean windHasGrowIcon, currAppWind = true;
- extern DialogPtr helpPtr;
-
-
-
-
- Boolean isActive (WindowPtr window) {
-
-
- return (gInForeGround && (window != nil) && ((WindowPeek)window)->hilited);
-
- } /* isActive */
-
-
-
- void DoWindow (void) {
-
- static short windowCount, newCount;
- short windowLoc;
-
-
- } /* DoWindow */
-
-
-
- short GetWindowType (WindowPtr window) {
-
- short RomMapInsertLoc = 0x0B9E;
- /* short mapTrue = -1; */
-
- short varCode, WDEFRsrcID, wType;
- Handle WDEFHandle;
- ResType WDEFType;
- Str255 WDEFName;
-
-
- varCode = GetWVariant(window);
-
- /* Now, what about rDocProc types since their Variation
- Codes duplicate those of some standard types such as
- documentProc & dBoxProc. I could call:
-
- regionSize = (**(((WindowPeek)window)->strucRgn)).rgnSize;
-
- If regionSize = 10, then rgnBBox is rectangular; so
- if <> 10, we've got an rDocProc. HOWEVER, if the
- window is invisible because I've not yet called
- _ShowWindow, rgnBBox is empty and regionSize STILL
- equals 10. The solution is simple ... call
- GetWindowType when the window is being activated.
- Better yet ... the solution presented below, thanks
- to MacDTS, avoids this workaround. In addition,
- MacDTS' solution avoids the pitfalls of "Murphy"
- inventing a totally new window type with a regionSize
- that dupes that of rDocProc. */
-
- /*
- Simple looking, ain't it !*?*!
- WDEFHandle = (Handle)QuickStrip((longPtr)(*((WindowPeek)window)).windowDefProc);
- */
-
- WDEFHandle = ((WindowPeek)window)->windowDefProc; // Even neater !!
- WDEFHandle = (Handle)QuickStrip((longPtr)WDEFHandle);
- ;
- LoadResource(WDEFHandle); /* May have been purged ... */
- *((wordPtr)RomMapInsertLoc) = mapTrue; /* Thanks, Ben Cranston !! */
- GetResInfo(WDEFHandle, &WDEFRsrcID, &WDEFType, WDEFName);
-
- wType = 16 * WDEFRsrcID + varCode; // = ProcID.
-
- return (wType);
-
- } /* GetWindowType */
-
-
-
- Boolean hasGrowIcon (WindowPtr window) {
-
- short wType;
-
-
- wType = GetWindowType(window);
- if ( (wType == documentProc) || (wType == zoomDocProc) )
- return (true);
- else
- return ( (ScrollHoriz(window) != nil) || (ScrollVert(window) != nil) );
-
- } /* hasGrowIcon */
-
-
-
- /* ---------------------------------------------------------------
- Make a separate PROC so we can zoom independently of _TrackBox,
- for example, in response to a Menu selection or a keypress:
- --------------------------------------------------------------- */
-
- void DoZoom (WindowPtr window, short zoomDir) {
- /* Reference: Tech Note #79 */
-
- typedef WStateData *WStateDataPtr, **WStateDataHdl;
-
- GrafPtr oldPort;
- WindowPeek wPeek;
- Rect r, windRect, zoomRect;
- GDHandle dominantGDevice;
- short bias;
-
-
- wPeek = (WindowPeek)window; /* Looks less messy below !!! */
-
- if ( (window == nil) || (wPeek->windowKind != userKind) ) return;
- ;
- GetPort(&oldPort);
- SetPort(window);
-
- /* If there is the possibility of multiple gDevices, then we must check them
- to make sure we are zooming onto the right display device when zooming out. */
- if ((zoomDir == inZoomOut) && gMac2) {
-
- /* Window's portRect must be converted to global coordinates: */
- windRect = window->portRect;
- LocalGlobal(&windRect);
-
- /* Must calculate height of window's title bar */
- bias = windRect.top - 1 - (**(wPeek->strucRgn)).rgnBBox.top;
- windRect.top = windRect.top - bias;
-
- dominantGDevice = GetMaxAreaDevice(&windRect);
-
- /* We must create a zoom rectangle manually in this case &
- account for menu bar height as well, if on main device. */
- if (dominantGDevice == GetMainDevice()) bias = bias + gMBarHt;
-
- r = (**dominantGDevice).gdRect;
- SetRect(&zoomRect,
- r.left + 3,
- r.top + bias + 3,
- r.right - 3,
- r.bottom - 3);
-
- /* Set up the WStateData record for this window. */
- (*(WStateDataHandle)(wPeek->dataHandle))->stdState = zoomRect;
-
- } /* inZoomOut & color Quickdraw */
-
- EraseRect(&(window->portRect));
- ShowHide(window, false);
- ZoomWindow(window, zoomDir, false); /* NO Activate Event !! */
- InvalRect(&(window->portRect));
- ScrollResize(window);
- ShowHide(window, true);
-
- switch(zoomDir) {
-
- case inZoomOut: PlaySound("ZoomOut"); break;
-
- case inZoomIn: PlaySound("ZoomIn"); break;
-
- } /* switch */
-
- SetPort(oldPort);
-
- } /* DoZoom */
-
-
-
- WindowPtr SelectNextWindow (void) {
-
- WindowPtr fWind;
- WindowPeek wind2, wind3;
-
-
- fWind = FrontWindow();
- wind2 = ((WindowPeek)fWind)->nextWindow;
- wind3 = wind2->nextWindow;
- /* System 6.xx w/DA in application heap: */
- while ((wind2 != nil) && (wind2->windowKind != userKind)) {
- wind2 = wind2->nextWindow;
- } /* while */
- ;
- if (wind2 != nil) {
- SelectWindow((WindowPtr)wind2);
- /* What used to be the front window, send to back
- so we rotate windows in a circular fashion */
- if (wind3 != nil) SendBehind(fWind, nil);
- } /* outer if */
-
- return ((WindowPtr)wind2);
-
- } /* SelectNextWindow */
-
-
-
- /* ---------------------------------------------------------
- ** CanNOT use the "structRgn" field of the window since this
- ** region handle will be NIL if the window is NOT visible.
- ** --------------------------------------------------------- */
-
- void CalcWindowFrame (WindowPtr window, Rect *r) {
-
-
- windType = GetWindowType(window) % 16;
-
- *r = window->portRect;
- InsetRect(r, -frame, -frame);
- if ((windType == 0) || (windType > 3))
- r->top = r->top - title; /* Window has a title bar. */
- if (
- (windType == documentProc) || (windType == altDBoxProc) ||
- (windType == noGrowDocProc) || (windType == zoomDocProc)
- )
- {
- r->bottom = r->bottom + shadow;
- r->right = r->right + shadow;
- } /* Window has a shadow frame. */
-
- } /* CalcWindowFrame */
-
-
-
- void CenterWindow (WindowPtr window) {
- /* Centers window on MAIN screen. */
-
- Rect screen, wFrameRect;
- short temp;
- Point Pt;
-
-
- CalcWindowFrame(window, &wFrameRect); // Calculates windType.
-
- if (gMac2) screen = (**GetMainDevice()).gdRect; // = global.
- else screen = screenBits.bounds; // Here, local = global.
- screen.top = screen.top + gMBarHt; // Below MenuBar.
-
- temp = screen.bottom - screen.top;
- /* screen height - window height: */
- temp = temp - (wFrameRect.bottom - wFrameRect.top);
- temp = temp / 2;
- temp = temp + frame;
- if ((windType == 0) || (windType > 3))
- temp = temp + title; // Window has a title bar.
- Pt.v = screen.top + temp;
- /* ----- */
- temp = screen.right - screen.left;
- /* screen width - window width: */
- temp = temp - (wFrameRect.right - wFrameRect.left);
- Pt.h = screen.left + temp / 2 + frame;
-
- MoveWindow(window, Pt.h, Pt.v, TRUE);
-
- } /* CenterWindow */
-
-
-
- /* -----------------------------------------------------
- ** Before showing the window, position it on the screen.
- ** ----------------------------------------------------- */
-
- void DisplayWindow (WindowPtr window, Boolean activate) {
-
- WindowPtr frontWindow;
- Boolean extraField;
- Str255 wTitle;
- short index, windType, rType;
- Handle rHdl;
-
-
- frontWindow = FrontWindow(); /* anyKind */
- if (!frontWindow) {
-
- if (!gSys7) extraField = false;
- else
- {
- extraField = false; // Assume NOT there !!
-
- windType = GetWindowType(window);
- GetWTitle(window, wTitle);
- ;
- for (index = 1; index <= Count1Resources('WIND'); index++)
- {
- rHdl = Get1IndResource('WIND', index);
- if (rHdl == nil) continue;
- asm {
- move.l rHdl, a0
- move.l (a0), a0
- move.w 8(a0), rType
- }
- // Compare window types:
- if (windType == rType) {
- /*
- oldType | newType
- ------- | -------
- 18 + 1 + len | a) odd length: 18 + 1 + len + 2
- | b) even length: 18 + 1 + len + fill byte + 2
- */
- if ( GetHandleSize(rHdl) > 18 + 1 + wTitle[0] + 1 )
- extraField = true;
- break;
- }
- } /* end for-loop */
-
- } // System 7.
-
- if (!extraField) CenterWindow(window);
- /* else do what the extra field stipulates. */
-
- } /* NO front window */
-
- else {
-
- Rect screenRect, frontWindRect, myWindRect;
- Point whereTL, whereBR;
- short myWindWidth, myWindHeight;
-
-
- if ( !((WindowPeek)window)->visible /* brand new */ ||
- EmptyRgn(window->visRgn) /* totally hidden */ ) {
-
- if (gMac2) screenRect = (**GetMainDevice()).gdRect;
- else screenRect = screenBits.bounds;
- // Get below MenuBar and accomodate for a possible window Title Bar:
- screenRect.top = screenRect.top + gMBarHt + 20;
-
- // GetPort(¤tWindow /* = passed window */);
- SetPort(frontWindow);
- ;
- frontWindRect = frontWindow->portRect;
- LocalGlobal(&frontWindRect);
- ;
- SetPort(window);
-
- /* Try to get WHOLE window to fit on screen &
- ** NOT obscure any of the existing front window: */
-
- myWindRect = window->portRect;
- myWindWidth = myWindRect.right - myWindRect.left;
- myWindHeight = myWindRect.bottom - myWindRect.top;
- whereBR = botRight(frontWindRect);
- // PortRect starts BELOW possible Title Bar:
- SetPt(&whereTL, whereBR.h + 5, whereBR.v + 25);
- SetPt(&whereBR, whereTL.h + myWindWidth, whereTL.v + myWindHeight);
- if ( !PtInRect(whereBR, &screenRect) ) {
- whereTL = topLeft(frontWindRect);
- SetPt(&whereBR, whereTL.h - 5, whereTL.v - 5);
- SetPt(&whereTL, whereBR.h - myWindWidth, whereBR.v - myWindHeight);
- if ( !PtInRect(whereTL, &screenRect) ) whereTL = topLeft(screenRect);
- }
- MoveWindow (window, whereTL.h, whereTL.v, activate);
-
- } /* end: moving the window */
-
- } /* somein in front */
-
- if (activate) ShowWindow(window);
- else ShowHide(window, TRUE);
- ;
- ScrollResize(window);
-
- } /* DisplayWindow */
-
-
-
- void CloseOurWindow (WindowPtr window) {
-
- PaletteHandle pal;
- PicHandle myPic;
- TEHandle textH;
-
-
- if (window == nil) return;
-
- if ( ((WindowPeek)window)->windowKind < 0)
- CloseDeskAcc( ((WindowPeek)window)->windowKind );
-
- else if (window == helpPtr) Kill_Help_Window();
- else {
-
- if (gMac2) {
- pal = GetPalette(window);
- if (pal != nil) DisposePalette(pal);
- } /* a Mac2 */
-
- myPic = GetWindowPic(window);
- if (myPic != nil) {
- HUnlock(myPic);
- ReleaseResource(myPic);
- }
-
- textH = (TEHandle)GetWRefCon(window);
- if (textH != nil) TEDispose(textH);
-
- DisposeWindow(window);
-
- } /* neither a DA nor our Help Window */
-
- } /* CloseOurWindow */
-
-
-
- /* -----------------------------------------------------------
- ** DoCloseAll is called from within "DoQuit". Note that we
- ** close windows from back to front by calling CloseBehind
- ** recursively. In this manner, window updating is minimized.
- ** Reference: APDA's "Programmer's Guide to MultiFinder" [B-5]
- ** ----------------------------------------------------------- */
-
- void DoCloseAll (void) {
-
-
- CloseBehind(FrontWindow());
-
- } /* DoCloseAll */
-
-
- void CloseBehind (WindowPtr window) {
-
- WindowPeek next;
-
-
- if (window != nil) {
- next = ((WindowPeek)window)->nextWindow;
- CloseBehind( (WindowPtr) (next) );
- CloseOurWindow(window);
- }
-
- } /* CloseBehind */
-
-
-
- /* { end file "window.c" } */
-